<!DOCTYPE html>
<html lang="en">


  
<head>
  <meta charset="UTF-8" />
  <!-- <link rel="icon" href="/favicon.ico" /> -->

  <style type="text/css">
    .loader:before {
      content: '';
      display: block;
      padding-top: 100%;
    }

    .circular {
      animation: rotate 2s linear infinite;
      height: 100%;
      transform-origin: center center;
      width: 100%;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
    }

    .path {
      stroke-dasharray: 1, 200;
      stroke-dashoffset: 0;
      animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
      stroke-linecap: round;
    }

    @keyframes rotate {
      100% {
        transform: rotate(360deg);
      }
    }

    @keyframes dash {
      0% {
        stroke-dasharray: 1, 200;
        stroke-dashoffset: 0;
      }

      50% {
        stroke-dasharray: 89, 200;
        stroke-dashoffset: -35px;
      }

      100% {
        stroke-dasharray: 89, 200;
        stroke-dashoffset: -124px;
      }
    }

    @keyframes color {

      100%,
      0% {
        stroke: #0960bd
      }

      40% {
        stroke: #0960bd
      }

      66% {
        stroke: #0960bd
      }

      80%,
      90% {
        stroke: #0960bd
      }
    }

    body {}

    .showbox {
      position: fixed;
      top: 0%;
      left: 0%;
      width: 100%;
      height: 100%;
      background-color: #eee;
      z-index: 2;
    }

    .loader {
      position: relative;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 100px;
    }

    #app {
      transform: translate3d(0, 0, 0);
    }
  </style>
  <!-- <link rel="stylesheet" href="./node_modules/animate.css/animate.min.css"> -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>llt-admin</title>
  <!-- <script type='text/javascript'
    src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=[YOUR_BING_MAPS_KEY]' 
    async defer></script> -->
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.85/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.85/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<script>
  var _hmt = _hmt || [];
  (function () {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?b60de4dc7ad96433035e4d328614a27f";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
  })();
</script>

<body>
  <div class="showbox" id="showbox">
    <div class="loader">
      <svg class="circular" viewBox="25 25 50 50">
        <circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="3" stroke-miterlimit="10" />
      </svg>
    </div>
  </div>
  <div id="app">

  </div>
  <script type="module" src="/src/main.ts"></script>
</body>

</html>
<script src="./event.js"></script>
<script>
  //   window.onload = function() {
  // let  entries = window.performance.getEntriesByType('resource');
  //  let ajax = entries
  //  console.log('ajax :>> ', ajax);
  // }

  //监听触发操作
  // 获取页面资源加载的时间性能信息
  const monitor = { // 前端监控
    performance: null, // 性能
    resources: {}, // 资源
    errors: [] // 错误
  }
  //页面 性能统计
  const pageEventData = {

  }
  // 获取页面加载的时间性能信息
  function getPerformance() {
    if (!window.performance) return
    const timing = window.performance.timing
    return {
      whiteScreen: timing.domLoading - timing.navigationStart, // 白屏时间
      redirect: timing.redirectEnd - timing.redirectStart, // 重定向耗时
      dom: timing.domComplete - timing.domLoading, // dom渲染耗时
      load: timing.loadEventEnd - timing.navigationStart, // 页面加载耗时
      unload: timing.unloadEventEnd - timing.unloadEventStart, // 页面卸载耗时
      request: timing.responseEnd - timing.requestStart, // 请求耗时
      time: new Date().getTime(), // 获取性能信息时当前时间
    }
  }
  //过滤上一次的数据 确保当前页面所记录的数据
  function filterLastData(resourcesNew, resourcesOld) {

    let obj = {}
    if (JSON.stringify(resourcesOld) == '{}') {
      return resourcesNew
    }
    for (const key in resourcesOld) {
      if (Object.hasOwnProperty.call(resourcesOld, key)) {
        const element = resourcesOld[key];
        if (Boolean(element) && Array.isArray(element)) {
          obj[key] = resourcesNew[key].slice(element.length)

        }

      }
    }

    return obj
  }
  // 获取页面资源加载的时间性能信息
  function getResources() {
    if (!window.performance) return
    const data = window.performance.getEntriesByType('resource')


    const resources = {
      css: [],
      img: [],
      script: [],
      xmlhttprequest: [],
      link: [],
      fetch: [],
      iframe: [],
      other: [],
      time: new Date().getTime()  // 获取资源信息时当前时间
    }
    data.forEach(item => {
      let key = resources[item.initiatorType] ? item.initiatorType : 'other'
      resources[key].push({
        name: item.name, // 资源的名称
        duration: item.duration.toFixed(2), // 资源加载耗时
        size: item.transferSize, // 资源大小
        protocol: item.nextHopProtocol, // 资源所用协议
      })
    })
    return resources
  }
  // 采集页面错误
  function collectError() {
    // 资源加载错误数据采集
    addEventListener('error', e => {
      const target = e.target
      console.log('error :>> ',target);
      if (target != window) {
        monitor.errors.push({
          type: target.localName,
          url: target.src || target.href,
          msg: (target.src || target.href) + ' is load error',
          time: new Date().getTime(), // 错误发生的时间
        })
      }
    }, true)
    // 监听js错误
    window.onerror = function (msg, url, row, col, error) {
      monitor.errors.push({
        type: 'javascript',
        row: row,
        col: col,
        msg: error && error.stack ? error.stack : msg,
        url: url,
        time: new Date().getTime(), // 错误发生的时间
      })
    }
    // 监听 promise 错误 缺点是获取不到行数数据
    addEventListener('unhandledrejection', e => {
      console.log('unhandledrejection :>> ',);
      monitor.errors.push({
        type: 'promise',
        msg: (e.reason && e.reason.msg) || e.reason || '',
        time: new Date().getTime(), // 错误发生的时间
      })
    })
  }
  var url = window.location.href;
  //监听页面变更  true更新 false 没有更新
  function isUpdatePage(value) {
    let bool = true;
    if (url != value) {
      console.log('object :>>页面更新了 ');
      bool = true;
    } else {
      console.log('object :>>页面没有更新了 ');
      bool = false
    }
    url = value;
    return bool;
  }

  window.unload = function () { // 在页面卸载的时候上报错误数据
    // uploadMonitorErrors()
    console.log('在页面卸载的时候上报错误数据 :>> ',);
  }
  window.onload = () => {

  }
  collectError()
  //监听触发操作
  let count = 0;//记录更新提交数据次数
  let init = (num) => {
    let href = url
    //页面更新 保存数据
    let jsonCopy = JSON.parse(JSON.stringify(monitor));
    if (isUpdatePage(window.location.href)) {
      count += 1;
      pageEventData[href] = jsonCopy
      localStorage.setItem('pageEventData', JSON.stringify(pageEventData))
    }
    monitor.performance = getPerformance()
    monitor.resources = getResources()

    //     if(count==0){
    //       count += 1
    //   let jsonCopy = JSON.parse(JSON.stringify(monitor));
    //   //第一次
    //   pageEventData[window.location.href] = jsonCopy
    //       localStorage.setItem('pageEventData',JSON.stringify(pageEventData))
    // }
  }
  let initEvent = () => {


    if (window.requestIdleCallback) { // 如果浏览器支持这个方法，利用这个方法采集页面性能数据
      window.requestIdleCallback(() => {

        init()
      })
    } else {
      setTimeout(function () {

        init()
      }, 0)
    }
    console.log('timing :>> ', monitor);
    //第一次页面加载完毕提交


  }




  let ji = document.querySelector("body")

  let observe = new MutationObserver(function (mu, ob) {
    //dom 更新后监控页面性能
    //  let data  =   getResources()
    //   console.log('timing :>> ', data);
    initEvent()

  })
  observe.observe(ji, { childList: true });




</script>

<script>
  var _hmt = _hmt || [];
  (function() {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?b60de4dc7ad96433035e4d328614a27f";
    var s = document.getElementsByTagName("script")[0]; 
    s.parentNode.insertBefore(hm, s);
  })();
  </script>